package net.peelmeagrape.hibernate.collections;

import net.peelmeagrape.hibernate.xmlgen.XmlAttribute;
import net.peelmeagrape.hibernate.xmlgen.XmlElement;
import net.peelmeagrape.hibernate.xmlgen.DefaultFromGenericType;
import net.peelmeagrape.hibernate.NotFoundSetting;

import java.lang.annotation.Retention;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

/**
 * <p>
 * A <em>one to many association</em> links the tables of two classes
 * via a foreign key, with no intervening collection table. This mapping loses
 * certain semantics of normal Java collections:</p>
 * <ul compact="compact" type="disc">
 * <li><p>
 *    An instance of the contained entity class may not belong to more than
 *    one instance of the collection
 * </p></li><li><p>
 *    An instance of the contained entity class may not appear at more than
 *    one value of the collection index
 * </p></li></ul>
 * <p>
 * Very important note: If the foreign key column of a
 * {@link OneToMany} association is declared NOT NULL, you must declare the
 * {@link net.peelmeagrape.hibernate.collections.Key} mapping not-null="true" or use a bidirectional association with
 * the collection mapping marked inverse="true". See
 * <a href="{@docRoot}/reference/en/html/collections.html#collections-bidirectional">Bidirectional associations</a>
 * for more info.
 */
@Retention(RUNTIME)
@XmlElement(name="one-to-many")
public @interface OneToMany
{
    /**
     * The type of the entity this collection contains. If you annotate a generified type, will attempt
     * to get the type from that, e.g.:
     * <pre>@H8List(
    key=@Key(),
    listIndex=@ListIndex(),
    value=@CollectionValue(element=@H8Element)
)
public List&lt;String> items;
     * </pre>
     * will find the type <code>java.lang.String</code>.
     */
    @XmlAttribute("class")
    @DefaultFromGenericType(-1)
            Class[] value() default {};

    /**
     * Specifies how cached identifiers that reference missing rows will be handled:
     * ignore will treat a missing row as a null association.
     */
    @XmlAttribute("not-found") NotFoundSetting notFound() default NotFoundSetting.EXCEPTION;
    @XmlAttribute String node() default "";
    @XmlAttribute("embed-xml") boolean embedXml() default true;
    @XmlAttribute("entity-name") String entityName() default "";
}
